require 'net/http'
require 'uri'
require 'yaml'
require 'fileutils'
require 'system_util'

class Fetcher

  def self.install_nginx(g)
    puts 'Downloading Nginx...'
    # tmp_nginx = fetch(g.tmp_nginx_path, g.remote_nginx_url)
    dir = File.dirname(g.target_nginx_tarball)
    FileUtils.mkdir_p(dir)
    FileUtils.cp("/opt/cf-static/nginx/1.3/nginx-1.3.3.tar.gz", g.target_nginx_tarball)

    puts 'Unpacking Nginx...'
    FileUtils.mkdir_p(g.nginx_tar_out_dir)
    tar_output = SystemUtil.run_with_err_output "tar pxzf #{g.target_nginx_tarball} -C #{g.nginx_tar_out_dir}"

    FileUtils.rm_rf g.target_nginx_tarball
    mv_tar_out_dir_to_target_dir(g.nginx_tar_out_dir, g.nginx_dir)

    unless File.exists?("#{g.nginx_dir}/sbin/nginx")
      puts 'Unable to retrieve the Nginx'
      puts tar_output
      exit 1
    end

    config_nginx(g)

  end

  def self.install_php(g)
    puts 'Downloading php...'
    # php_version = File.basename(File.dirname(g.remote_php_url))
    # tmp_php = fetch(g.tmp_php_path, g.remote_php_url)
    php_version = '5.5'
    dir = File.dirname(g.target_php_tarball)
    FileUtils.mkdir_p(dir)
    FileUtils.cp("/opt/cf-static/php/5.5/php-5.5.9-bin.tar.gz", g.target_php_tarball)

    puts 'Unpacking php....'
    FileUtils.mkdir_p(g.php_tar_out_dir)
    tar_output = SystemUtil.run_with_err_output "tar pxzf #{g.target_php_tarball} -C #{g.php_tar_out_dir}"

    FileUtils.rm_rf g.target_php_tarball

    mv_tar_out_dir_to_target_dir(g.php_tar_out_dir, g.php_dir)

    unless File.exists?("#{g.php_dir}/bin/php")
      puts 'Unable to retrieve the php'
      puts tar_output
      exit 1
    end

    config_php(g, php_version)

  end

  def self.mv_tar_out_dir_to_target_dir(tar_out_dir, target_dir)
    FileUtils.mkdir_p(target_dir)
    FileUtils.rm_rf(target_dir)

    entries = Dir.entries(tar_out_dir)
    file_cnt = entries.length
    if file_cnt > 3
      FileUtils.mv(tar_out_dir, target_dir)
    else
      real_dir = entries.detect do |entry|
        entry != '.' and entry != '..'
      end
      FileUtils.mv(File.join(tar_out_dir, real_dir), target_dir)
    end
  end

  def self.config_nginx(g)
    puts 'Config Nginx...'
    if File.exist?(g.user_nginx_conf)
      FileUtils.mv(g.user_nginx_conf, g.target_nginx_conf)
    else
      FileUtils.mv(g.default_nginx_conf, g.target_nginx_conf)
    end

    if File.exist?(g.user_mime_types)
      FileUtils.mv(g.user_mime_types, g.target_mime_types)
    else
      FileUtils.mv(g.default_mime_types, g.target_mime_types)
    end
    puts 'Nginx installed'
  end

  def self.config_php(g, php_version)
    puts 'Config php...'
    if File.exist?(g.user_php_ini)
      FileUtils.mv(g.user_php_ini, g.target_php_ini)
    else
      FileUtils.mv(g.default_php_ini(php_version), g.target_php_ini)
    end

    if File.exist?(g.user_php_fpm_conf)
      FileUtils.mv(g.user_php_fpm_conf, g.target_php_fpm_conf)
    else
      FileUtils.mv(g.default_php_fpm_conf(php_version), g.target_php_fpm_conf)
    end
    puts 'php installed'
  end

  def self.copy_local(target_path, src_path)
    FileUtils.cp(src_path, target_path)
  end

  def self.fetch(file_path, url)
    puts "Downloading #{file_path} from #{url} ... "

    dir = File.dirname(file_path)
    FileUtils.mkdir_p(dir)
    File.open(file_path, 'w') do |tf|
      begin
        Net::HTTP.get_response(URI.parse(url)) do |response|
          unless response.is_a?(Net::HTTPSuccess)
            puts 'Could not fetch file (%s): %s/%s' % [file_path, response.code, response.body]
            return
          end

          response.read_body do |segment|
            tf.write(segment)
          end
        end
      ensure
        tf.close
      end
    end
    file_path
  end

end
